Skip to main content

aviutl2\filter\binding/
mod.rs

1mod audio;
2mod video;
3
4pub use audio::*;
5pub use video::*;
6
7use super::config;
8use crate::common::Rational32;
9
10/// 入力プラグインの情報を表す構造体。
11#[derive(Debug, Clone)]
12pub struct FilterPluginTable {
13    /// プラグインの名前。
14    pub name: String,
15    /// ラベルの初期値。
16    /// Noneの場合、デフォルトのラベルになります
17    pub label: Option<String>,
18    /// プラグインの情報。
19    /// 「プラグイン情報」ダイアログで表示されます。
20    pub information: String,
21
22    /// 対応している機能のフラグ。
23    pub flags: FilterPluginFlags,
24
25    /// 設定項目。
26    pub config_items: Vec<config::FilterConfigItem>,
27}
28
29define_bitflag! {
30    /// フィルタプラグインのフラグ。
31    ///
32    /// # See Also
33    ///
34    /// - [`crate::bitflag!`]
35    #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)]
36    #[non_exhaustive]
37    pub struct FilterPluginFlags: i32 {
38        /// 画像フィルタをサポートするかどうか。
39        video: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_VIDEO,
40
41        /// 音声フィルタをサポートするかどうか。
42        audio: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_AUDIO,
43
44        /// 入力として動作するかどうか。
45        /// `true` の場合、カスタムオブジェクトとして動作します。
46        /// `false` の場合、フィルタ効果として動作します。
47        input: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_INPUT,
48
49        /// フィルタオブジェクトをサポートするかどうか。
50        /// `true` の場合、フィルタオブジェクトとして使えるようになります。
51        filter: aviutl2_sys::filter2::FILTER_PLUGIN_TABLE::FLAG_FILTER,
52    }
53}
54
55/// フィルタプラグインで使用するユーザーデータのトレイト。
56pub trait FilterUserdata: Send + Sync + Sized + 'static {
57    /// ユーザーデータを初期化する。
58    fn new(effect_id: i64) -> Self;
59}
60
61impl FilterUserdata for () {
62    fn new(_effect_id: i64) -> Self {}
63}
64
65/// フィルタプラグインのユーザーデータを参照するためのハンドル。
66#[derive(Debug)]
67pub struct FilterUserdataHandle<T: FilterUserdata> {
68    pub(crate) inner: std::sync::Arc<parking_lot::RwLock<T>>,
69}
70
71impl<T: FilterUserdata> FilterUserdataHandle<T> {
72    pub(crate) fn new(inner: std::sync::Arc<parking_lot::RwLock<T>>) -> Self {
73        Self { inner }
74    }
75
76    /// ユーザーデータを読み取るためのロックを取得する。
77    pub fn read(&self) -> FilterUserdataReadGuard<'_, T> {
78        FilterUserdataReadGuard {
79            inner: self.inner.read(),
80        }
81    }
82
83    /// ユーザーデータを読み取るためのロックの取得を試みる。
84    pub fn try_read(&self) -> Option<FilterUserdataReadGuard<'_, T>> {
85        self.inner
86            .try_read()
87            .map(|inner| FilterUserdataReadGuard { inner })
88    }
89
90    /// ユーザーデータを書き込むためのロックを取得する。
91    pub fn write(&self) -> FilterUserdataWriteGuard<'_, T> {
92        FilterUserdataWriteGuard {
93            inner: self.inner.write(),
94        }
95    }
96
97    /// ユーザーデータを書き込むためのロックの取得を試みる。
98    pub fn try_write(&self) -> Option<FilterUserdataWriteGuard<'_, T>> {
99        self.inner
100            .try_write()
101            .map(|inner| FilterUserdataWriteGuard { inner })
102    }
103}
104
105/// フィルタプラグインのユーザーデータを読み取るためのガード。
106pub struct FilterUserdataReadGuard<'handle, T: FilterUserdata> {
107    inner: parking_lot::RwLockReadGuard<'handle, T>,
108}
109
110impl<T: FilterUserdata> std::ops::Deref for FilterUserdataReadGuard<'_, T> {
111    type Target = T;
112
113    fn deref(&self) -> &Self::Target {
114        &self.inner
115    }
116}
117
118/// フィルタプラグインのユーザーデータを書き込むためのガード。
119pub struct FilterUserdataWriteGuard<'handle, T: FilterUserdata> {
120    inner: parking_lot::RwLockWriteGuard<'handle, T>,
121}
122
123impl<T: FilterUserdata> std::ops::Deref for FilterUserdataWriteGuard<'_, T> {
124    type Target = T;
125
126    fn deref(&self) -> &Self::Target {
127        &self.inner
128    }
129}
130
131impl<T: FilterUserdata> std::ops::DerefMut for FilterUserdataWriteGuard<'_, T> {
132    fn deref_mut(&mut self) -> &mut Self::Target {
133        &mut self.inner
134    }
135}
136
137/// フィルタプラグインのトレイト。
138/// このトレイトを実装し、[`crate::register_filter_plugin!`] マクロを使用してプラグインを登録します。
139pub trait FilterPlugin: Send + Sync + Sized {
140    /// エフェクト毎に保持するユーザーデータの型。
141    ///
142    /// 使用しない場合は`()`を指定してください。
143    type Userdata: FilterUserdata;
144
145    /// プラグインを初期化する。
146    fn new(info: crate::common::AviUtl2Info) -> crate::common::AnyResult<Self>;
147
148    /// プラグインの情報を返す。
149    fn plugin_info(&self) -> crate::filter::FilterPluginTable;
150
151    /// 画像フィルタ処理関数。
152    ///
153    /// # Note
154    ///
155    /// フィルタオブジェクトの場合、画像サイズは変更できません。
156    fn proc_video(
157        &self,
158        _config: &[crate::filter::FilterConfigItem],
159        _video: &mut crate::filter::FilterProcVideo<Self::Userdata>,
160    ) -> crate::common::AnyResult<()> {
161        anyhow::bail!("proc_video is not implemented");
162    }
163
164    /// 音声フィルタ処理関数。
165    fn proc_audio(
166        &self,
167        _config: &[crate::filter::FilterConfigItem],
168        _audio: &mut crate::filter::FilterProcAudio<Self::Userdata>,
169    ) -> crate::common::AnyResult<()> {
170        anyhow::bail!("proc_audio is not implemented");
171    }
172
173    /// シングルトンインスタンスを参照するためのヘルパーメソッド。
174    ///
175    /// # Panics
176    ///
177    /// プラグインが初期化されていない場合や、二重に呼び出された場合にパニックします。
178    fn with_instance<R>(f: impl FnOnce(&Self) -> R) -> R
179    where
180        Self: crate::filter::__bridge::FilterSingleton,
181    {
182        <Self as crate::filter::__bridge::FilterSingleton>::with_instance(f)
183    }
184
185    /// シングルトンインスタンスを可変参照するためのヘルパーメソッド。
186    ///
187    /// # Panics
188    ///
189    /// プラグインが初期化されていない場合や、二重に呼び出された場合にパニックします。
190    fn with_instance_mut<R>(f: impl FnOnce(&mut Self) -> R) -> R
191    where
192        Self: crate::filter::__bridge::FilterSingleton,
193    {
194        <Self as crate::filter::__bridge::FilterSingleton>::with_instance_mut(f)
195    }
196}
197
198/// シーン情報。
199#[derive(Debug, Clone, Copy)]
200pub struct SceneInfo {
201    /// 解像度(幅)。
202    pub width: u32,
203    /// 解像度(高さ)。
204    pub height: u32,
205    /// フレームレート。
206    pub frame_rate: Rational32,
207    /// サンプリングレート。
208    pub sample_rate: u32,
209}
210
211/// オブジェクト情報。
212///
213/// # Note
214///
215/// フレームは0-indexedです。
216#[derive(Debug, Clone, Copy)]
217pub struct ObjectInfo {
218    /// 描画対象のオブジェクトの固有ID。
219    /// アプリ起動ごとの固有IDです。
220    pub id: i64,
221    /// オブジェクトの内の対象エフェクトのID。
222    /// アプリ起動ごとの固有IDです。
223    pub effect_id: i64,
224    /// オブジェクトのレイヤー番号。
225    pub layer: u32,
226    /// オブジェクトの現在のフレーム番号。
227    pub frame: u32,
228    /// オブジェクトの総フレーム数。
229    pub frame_total: u32,
230    /// オブジェクトの現在の時間(秒)。
231    pub time: f64,
232    /// オブジェクトの総時間(秒)。
233    pub time_total: f64,
234    /// オブジェクトがフィルタオブジェクトかどうか。
235    pub is_filter_object: bool,
236    /// シーン基準のオブジェクトの開始フレーム。
237    pub frame_s: u32,
238    /// シーン基準のオブジェクトの終了フレーム。
239    pub frame_e: u32,
240    /// 対象エフェクトの現在のレイヤー番号。
241    pub effect_layer: u32,
242    /// シーン基準のレンダリングの起点フレーム。
243    pub origin_frame: u32,
244}
245
246impl ObjectInfo {
247    /// シーン基準のオブジェクトのフレーム範囲。
248    pub fn frame_range(&self) -> std::ops::RangeInclusive<u32> {
249        self.frame_s..=self.frame_e
250    }
251}
252
253/// フィルタ処理のエラー。
254#[derive(Debug, thiserror::Error)]
255pub enum FilterProcError {
256    #[error("api call failed")]
257    ApiCallFailed,
258    #[error("input string contains null byte")]
259    InputCwstrContainsNull(#[from] crate::common::NullByteError),
260    #[error("input string contains null byte")]
261    InputCstrContainsNull(#[from] std::ffi::NulError),
262    #[error("value is out of range")]
263    ValueOutOfRange,
264    #[error("filter config data is locked")]
265    FilterConfigDataLocked,
266    #[error("filter config data is not bound to the current filter process")]
267    FilterConfigDataNotBound,
268}
269
270pub type FilterProcResult<T> = Result<T, FilterProcError>;